#include "capalineatiempo.h"
#include "conversorunidades.h"
#include "entrenador.h"

CapaLineaTiempo::CapaLineaTiempo()
{
}

CapaLineaTiempo::~CapaLineaTiempo()
{
}

void CapaLineaTiempo::dibujarPartesEstaticas(QPainter* painter, const QRectF& encuadreReal, int anchoPixeles, int altoPixeles)
{
    ConversorUnidades conversor(encuadreReal, QRect(0, 0, anchoPixeles, altoPixeles));
    dibujarCompas(painter, &conversor, compas, encuadreReal, false);
}

void CapaLineaTiempo::dibujarPartesDinamicas(QPainter* painter, const QRectF& encuadreReal, int anchoPixeles, int altoPixeles)
{
    ConversorUnidades conversor(encuadreReal, QRect(0, 0, anchoPixeles, altoPixeles));
    dibujarCompas(painter, &conversor, compas, encuadreReal, true);
}


#define ANCHO 400
#define ALTO  100
#define MARGEN 0
#define RADIO 5

void CapaLineaTiempo::dibujarCompas(QPainter* painter, ConversorUnidades* conversor, const Compas& compas, const QRectF& encuadreReal, bool soloPartesDinamicas)
{
	Instrumento* instrumento = Entrenador::getInstancia()->getInstrumento();
	Interprete* interprete = Entrenador::getInstancia()->getInterprete();

	int numeroPulsos = compas.getNumeroPulsos();
	int numeroPiezas = instrumento->getNumeroPiezas();

	double separacionX = (ANCHO - 2.0 * MARGEN) / numeroPulsos;
	double separacionY = (ALTO - 2.0 * MARGEN) / numeroPiezas;

	double xInicial = MARGEN;
	double yInicial = MARGEN;
	double xFinal = ANCHO - MARGEN;
	double yFinal = ALTO - MARGEN;

    if (!soloPartesDinamicas) {
	    painter->setPen(Qt::gray);
	    // Lineas de separacion horizontales
	    for (int i = 0; i <= numeroPiezas; i++) {
		    double y = MARGEN + i * separacionY;
		    QPoint p1 = conversor->puntoRealAPixeles(QPoint(xInicial, y));
		    QPoint p2 = conversor->puntoRealAPixeles(QPoint(xFinal, y));
		    painter->drawLine(p1, p2);
	    }
    	
	    // Lineas de separacion verticales
	    for (int i = 0; i <= numeroPulsos; i++) {
		    double x = MARGEN + i * separacionX;
		    QPoint p1 = conversor->puntoRealAPixeles(QPoint(x, yInicial));
		    QPoint p2 = conversor->puntoRealAPixeles(QPoint(x, yFinal));
		    painter->drawLine(p1, p2);
	    }
	
	    // Notas del compas de entrenamiento
	    painter->setBrush(Qt::white);
	    painter->setPen(Qt::black);
	    for (int i = 0, n = compas.getNumeroNotas(); i < n; i++) {
		    NotaCompas nota = compas.getNota(i);
            if (!nota.esValida()) {
                continue;
            }

		    int indiceY = instrumento->getIndiceNota(nota.getNombreNota());

		    double proporcionDivision = ((double) nota.getDivision()) / nota.getDivisiones();
		    double x = xInicial + (nota.getPulso() + proporcionDivision) * separacionX;
		    double y = yInicial + indiceY * separacionY; 
		    QRectF renctanguloRealNota(x - RADIO, y - RADIO, RADIO * 2, RADIO * 2);
		    QRect rectanguloPixelesNota = conversor->rectanguloRealAPixeles(renctanguloRealNota);
		    painter->drawEllipse(rectanguloPixelesNota);
	    }
        return;
    } 

	// Notas del usuario
	QList<NotaRegistrada> listaNotas = Entrenador::getInstancia()->getListaNotasRegistradasUsuario();
	quint64 milisegundoInicio = interprete->getMilisegundoInicioCompas();
	double milisegundosPorCompas = interprete->getMilisegundosPorCompas();

	foreach (NotaRegistrada notaRegistrada, listaNotas) {
	
		int indiceY = instrumento->getIndiceNota(notaRegistrada.nota);
		if (indiceY < 0) {
			continue;
		}
		quint64 milisegundo = notaRegistrada.milisegundo;

		double milisegundoRelativo;
		if (milisegundo < milisegundoInicio) {
			milisegundoRelativo = - (double) (milisegundoInicio - milisegundo);
		} else {
			milisegundoRelativo = milisegundo - milisegundoInicio;
		}
		double proporcionTiempo = milisegundoRelativo / milisegundosPorCompas;

		double x = xInicial + proporcionTiempo * (xFinal - xInicial) ;
		double y = yInicial + indiceY * separacionY; 
		QRectF renctanguloRealNota(x - RADIO, y - RADIO, RADIO * 2, RADIO * 2);
		QRect rectanguloPixelesNota = conversor->rectanguloRealAPixeles(renctanguloRealNota);

        QColor color = Entrenador::getInstancia()->getColorNota(notaRegistrada.nota);
        painter->setPen(color);
        color.setAlpha(175);
        painter->setBrush(color);
		painter->drawEllipse(rectanguloPixelesNota);
	}

	// Linea de instante actual
	double proporcionX = Entrenador::getInstancia()->getProporcionCompletadoCompas();
	double x = xInicial + proporcionX * (xFinal - xInicial);
	QPoint p1 = conversor->puntoRealAPixeles(QPoint(x, yInicial));
	QPoint p2 = conversor->puntoRealAPixeles(QPoint(x, yFinal));
	painter->setPen(Qt::red);
	painter->drawLine(p1, p2);

}
